﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
#if (WINRT)
using Windows.UI.Xaml;
#elif (COMPOSITION)
#else
using System.Windows;
#endif

namespace nRoute.Utilities
{
    public static class Compatability
    {

#if (WINRT)
        public const StringComparison INVARIANT_IGNORECASE_STRING_COMPARISION = StringComparison.OrdinalIgnoreCase;
        public const StringComparison INVARIANT_STRING_COMPARISION = StringComparison.OrdinalIgnoreCase;
        public const StringComparison CURRENTCULTURE_IGNORECASE_STRING_COMPARISION = StringComparison.CurrentCultureIgnoreCase;
        public const StringComparison CURRENTCULTURE_STRING_COMPARISION = StringComparison.CurrentCulture;

        public readonly static StringComparer INVARIANT_IGNORECASE_STRING_COMPARER = StringComparer.OrdinalIgnoreCase;
        public readonly static StringComparer INVARIANT_STRING_COMPARER = StringComparer.OrdinalIgnoreCase;
        public readonly static StringComparer CURRENTCULTURE_IGNORECASE_STRING_COMPARER = StringComparer.CurrentCultureIgnoreCase;
        public readonly static StringComparer CURRENTCULTURE_STRING_COMPARER = StringComparer.CurrentCulture;
#else
        public const StringComparison INVARIANT_IGNORECASE_STRING_COMPARISION = StringComparison.InvariantCultureIgnoreCase;
        public const StringComparison INVARIANT_STRING_COMPARISION = StringComparison.InvariantCulture;
        public const StringComparison CURRENTCULTURE_IGNORECASE_STRING_COMPARISION = StringComparison.CurrentCultureIgnoreCase;
        public const StringComparison CURRENTCULTURE_STRING_COMPARISION = StringComparison.CurrentCulture;

        public readonly static StringComparer INVARIANT_IGNORECASE_STRING_COMPARER = StringComparer.InvariantCultureIgnoreCase;
        public readonly static StringComparer INVARIANT_STRING_COMPARER = StringComparer.InvariantCulture;
        public readonly static StringComparer CURRENTCULTURE_IGNORECASE_STRING_COMPARER = StringComparer.CurrentCultureIgnoreCase;
        public readonly static StringComparer CURRENTCULTURE_STRING_COMPARER = StringComparer.CurrentCulture;
#endif

#if (WP7)
        public readonly static int PROC_COUNT = 1;  // <-- WP7 joke here..
#else
        public readonly static int PROC_COUNT = Environment.ProcessorCount;
#endif

#if (WINRT || SILVERLIGHT)
        public readonly static Object DP_UNSET_VALUE = DependencyProperty.UnsetValue;
#else
        public readonly static Object DP_UNSET_VALUE = default(Object); // DependencyProperty.UnsetValue;
#endif


#if (WINRT)

        internal static Delegate ExpressionEg<E>(object target, MethodInfo method)
        {
            

            // todo: test this.. 
            // also see http://realfiction.net/go/204
            var _delegateType = typeof(Action<,>).MakeGenericType(typeof(object), typeof(E));
            var _p1 = Expression.Parameter(typeof(object));
            var _p2 = Expression.Parameter(typeof(E));

            var _target = Expression.Constant(target);
            var _call = Expression.Call(_target, method, _p1, _p2);
            var _delegate = Expression.Lambda(_delegateType, _call, _p1, _p2);

            return _delegate.Compile();
        }

        public static void ForEach<T>(this List<T> items, Action<T> action)
        {
            // note no nullability checks
            foreach (var _item in items)
            {
                action(_item);
            }
        }

#else

        public static bool IsGenericType(this Type type)
        {
            return type.IsGenericType;
        }

#endif

    }
}